﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Model.Items.Weapons;
using Model.Items;

namespace Model.Hero
{
    public class RagDoll
    {
        //what items does the hero/NPC wear in which slot

        //armor slots
        private Slot _head, _shoulder, _chest, _hands, _feet, _legs, _arms, _shield;
        //misc. amulets & rings
        private Slot _neck;
        private List<Slot> _fingers; //one for each 10 fingers
        //weapon slots
        private Slot _wpn_left, _wpn_right;

        private double _attack_rating, _defense_rating;


        public RagDoll()
        {
            _head = new Slot();
            _shoulder = new Slot();
            _chest = new Slot();
            _hands = new Slot();
            _feet = new Slot();
            _legs  = new Slot();
            _arms  = new Slot();
            _shield  = new Slot();
            _neck  = new Slot();
            _wpn_left = new Slot();
            _wpn_right = new Slot();
        }

        public Slot Head { get { return _head; } }
        public Slot Shoulder { get { return _shoulder; } }
        public Slot Chest { get { return _chest; } }
        public Slot Hands { get { return _hands; } }
        public Slot Feet { get { return _feet; } }
        public Slot Legs { get { return _legs; } }
        public Slot Arms { get { return _arms; } }        
        public Slot Shield { get { return _shield; } }
        public Slot Neck { get { return _neck; } }
        public Slot Weapon_Right { get { return _wpn_right; } }
        public Slot Weapon_Left { get { return _wpn_left; } }

        public void EquipItemInSlot(Item item, Slot slot)
        {
            //unequip item currently held in slot
            UnequipItem(slot);

            if (item as Weapon != null)
            {
                //cant equip two-handers in left hand. equip the normal way
                if (item.TwoHander && slot == _wpn_left)
                {
                    EquipItem(item);
                    return;
                }
                if (slot.Active && (slot == _wpn_left || slot == _wpn_right))
                {
                    slot.item = item;
                    slot.Equipped = true;
                }
            }
            //update att/def rating
            Attack_Rating += item.Attack_Rating;
            Defense_Rating += item.Defense_Rating;
        }

        public void EquipItem(Item item)
        {
            if (item as Weapon != null)
            {
                //unequip former item
                UnequipItem(_wpn_right);
                //put it in slot
                _wpn_right.item = item;
                //activate slot and set as equipped
                _wpn_right.Active = true;
                _wpn_right.Equipped = true;

                if (item.TwoHander)
                {
                    if (_wpn_left.Equipped)
                        UnequipItem(_wpn_left);
                    //disable left hand for weapons
                    _wpn_left.Active = false;
                }                
            }
            //update att/def rating
            Attack_Rating += item.Attack_Rating;
            Defense_Rating += item.Defense_Rating;
        }//end EquipItem

        public void UnequipItem(Slot slot)
        {
            if (slot.Equipped && slot.Active)
            {
                Attack_Rating -= slot.item.Attack_Rating;
                Defense_Rating -= slot.item.Defense_Rating;                
            }
            slot.Equipped = false;
            //activate slot
            slot.Active = true;
        }

        public double Attack_Rating
        {
            get
            {
                return _attack_rating;
                //brute force method
                //iterate through each item with and return the sum               
                /*return
                    (_wpn_right.Active && _wpn_right.Equipped ? _wpn_right.item.Attack_Rating : 0) +
                    (_wpn_left.Active && _wpn_left.Equipped ? _wpn_left.item.Attack_Rating : 0) +
                    (_chest.Active && _chest.Equipped ? _chest.item.Attack_Rating : 0) +
                    (_arms.Active && _arms.Equipped ? _arms.item.Attack_Rating  : 0) +
                    (_head.Active && _head.Equipped ? _head.item.Attack_Rating : 0) +
                    (_feet.Active && _feet.Equipped ? _feet.item.Attack_Rating : 0) +
                    (_hands.Active && _hands.Equipped ? _hands.item.Attack_Rating : 0) +
                    (_legs.Active && _legs.Equipped ? _legs.item.Attack_Rating : 0) +
                    (_neck.Active && _neck.Equipped ? _neck.item.Attack_Rating : 0) +
                    (_shield.Active && _shield.Equipped ? _shield.item.Attack_Rating : 0) +
                    (_shoulder.Active && _shoulder.Equipped ? _shoulder.item.Attack_Rating : 0);
                //*/
            }
            set
            {
                _attack_rating = value;
            }
        }

        public double Defense_Rating
        {
            get { return _defense_rating; }
            set
            {
                _defense_rating = value;
            }
        }
    }//end class ragdoll

    public class Slot
    {
        //active property currently servers little purpose
        private bool _active; //a slot could be disabled for various reasons, ex. equipping a twohander
        private bool _equipped; //is an item equipped in the slot
        private Item _item;

        public Slot()
        {
            Active = true;
            Equipped = false;
        }

        public Item item
        {
            get { return _item; }
            set
            {
                _item = value;
            }
        }

        public bool Active
        {
            get { return _active; }
            set
            {
                _active = value;
            }
        }

        public bool Equipped
        {
            get { return _equipped; }
            set
            {
                _equipped = value;
            }
        }
    }//end class slot
}
